package com.itjiange.service.impl;

import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.itjiange.common.BaseResponse;
import com.itjiange.common.ErrorCode;
import com.itjiange.constant.CommonConstant;
import com.itjiange.constant.UserConstant;
import com.itjiange.exception.BusinessException;
import com.itjiange.mapper.UserMapper;
import com.itjiange.model.dto.UserQueryDto;
import com.itjiange.model.dto.UserRequestDto;
import com.itjiange.model.dto.UserUpdateDto;
import com.itjiange.model.pojo.User;
import com.itjiange.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

/**
 * @author 大师的本
 * @description 针对表【user】的数据库操作Service实现
 * @createDate 2023-10-27 15:32:00
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {
    private final String SALZ = "jiange"; // 密码加盐

    @Autowired
    private UserMapper userMapper;

    /**
     * 用户登录
     *
     * @param userAccount 用户账号
     * @param password    用户密码
     * @param verCode
     * @param request
     * @return
     */
    @Override
    public BaseResponse<User> login(String userAccount, String password, String verCode, HttpServletRequest request) {
        // 校验
        if (StrUtil.hasEmpty(userAccount, password, verCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号为空或密码为空");
        }
        HttpSession httpSession = request.getSession();
        // 从 session 中获取验证码
        String captchaCode = (String) httpSession.getAttribute(CommonConstant.CAPTCHA);
        if (!verCode.equals(captchaCode)) {
            return new BaseResponse<>(ErrorCode.PARAMS_ERROR.getCode(), "验证码有误请重新登录");
        }
        // 移除 session 中的验证码
        httpSession.removeAttribute(CommonConstant.CAPTCHA);
        // 密码加密
        String passwordMD5 = SecureUtil.md5(password + SALZ);
        // 查询用户信息
        User user = userMapper.getUserByNameOrPass(userAccount, passwordMD5);
        if (user == null) { // 数据库中未存在该用户
            return new BaseResponse<>(ErrorCode.NOT_FOUND_ERROR.getCode(), "用户不存在或密码错误，请重新登录");
        }
        // 将用户信息暂存入 session
        httpSession.setAttribute(UserConstant.USER_STATUS, user);
        return new BaseResponse<>(CommonConstant.SUCCESS, user);
    }

    /**
     * 用户注册
     *
     * @param userRequestDto 用户请求信息
     * @param verCode
     * @param request
     * @return
     */
    @Override
    public BaseResponse<Integer> register(String userAccount, String password, String checkPassword, String verCode, HttpServletRequest request) {
        // 校验
        if (StrUtil.hasEmpty(userAccount, password, checkPassword, verCode)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "注册数据为空");
        }
        if (!password.equals(checkPassword)) {
            return new BaseResponse<>(ErrorCode.PARAMS_ERROR.getCode(), "两次输入的密码不一致");
        }
        if (password.length() < 6) {
            return new BaseResponse<>(ErrorCode.PARAMS_ERROR.getCode(), "密码长度小于 6 位");
        }
        // 根据账户查询是否已存在
        User user = userMapper.getUserByNameOrPass(userAccount, null);
        if (user != null) {
            return new BaseResponse(CommonConstant.ERROR, "账户已存在，请点击下方进行登录");
        }
        // 密码加密
        String passwordMD5 = SecureUtil.md5(password + SALZ);
        // 存入数据库
        UserRequestDto userRequestDto = new UserRequestDto();
        userRequestDto.setUserAccount(userAccount);
        userRequestDto.setPassword(passwordMD5);

        int flag = userMapper.insertUser(userRequestDto);

        if (flag < 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "插入数据失败");
        }
        return new BaseResponse<>(CommonConstant.SUCCESS, flag);
    }

    /**
     * 用户修改
     *
     * @param request
     * @return
     */
    @Override
    public BaseResponse<Integer> update(UserUpdateDto userUpdateDto, HttpServletRequest request) {
        // 从 session 中获取当前登录用户，并拿到用户 id
        HttpSession httpSession = request.getSession();
        User user = (User) httpSession.getAttribute(UserConstant.USER_STATUS);
        userUpdateDto.setId(user.getId());
        userUpdateDto.setAvatar(user.getAvatar());
        userUpdateDto.setPassword(SecureUtil.md5(userUpdateDto.getPassword() + SALZ));
        int flag = userMapper.updateUser(userUpdateDto);
        if (flag < 0) {
            return new BaseResponse<>(CommonConstant.ERROR, "修改失败", flag);
        }
        return new BaseResponse<>(CommonConstant.SUCCESS, "修改成功", flag);
    }

    /**
     * 用户修改 头像
     *
     * @param request
     * @return
     */
    @Override
    public BaseResponse<Integer> updateUserAvatar(String avatar, HttpServletRequest request) {
        // 从 session 中获取当前登录用户，并拿到用户 id
        HttpSession httpSession = request.getSession();
        User user = (User) httpSession.getAttribute(UserConstant.USER_STATUS);
        UserUpdateDto userUpdateDto = new UserUpdateDto();
        BeanUtils.copyProperties(user, userUpdateDto);
        userUpdateDto.setAvatar(avatar);
        user.setAvatar(avatar);
        httpSession.setAttribute(UserConstant.USER_STATUS, user);
        int flag = userMapper.updateUser(userUpdateDto);
        if (flag < 0) {
            return new BaseResponse<>(CommonConstant.ERROR, "修改失败", flag);
        }
        return new BaseResponse<>(CommonConstant.SUCCESS, "修改成功", flag);
    }

    /**
     * 获取用户登录信息
     *
     * @param request
     * @return
     */
    @Override
    public BaseResponse<User> getUserMessage(HttpServletRequest request) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute(UserConstant.USER_STATUS);
        // 获取头像路径
        String avatar = user.getAvatar();
        // 将头像路径转为 BASE64 存储
        String encoderAvatar = getAvatarEncoder(avatar);
        user.setAvatar(encoderAvatar);
        return new BaseResponse<>(CommonConstant.SUCCESS, "登录信息获取成功", user);
    }

    /**
     * 将路径转为 BASE64 存储
     *
     * @param avatar 头像路径
     * @return
     */
    private static String getAvatarEncoder(String avatar) {
        String encoder = "data:image/jpg;base64,"; //定义图片类型，方便前端直接使用
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        try (FileInputStream is = new FileInputStream(avatar)) {
            is.transferTo(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
        encoder = encoder + Base64Encoder.encode(data.toByteArray()).replace("\r\n", "").trim();
        return encoder;
    }

    /**
     * 查询所有用户
     *
     * @return
     */
    @Override
    public BaseResponse<List<User>> getAllUser() {
        List<User> allUser = userMapper.getAllUser();
        return new BaseResponse<>(CommonConstant.SUCCESS, "查询所有用户成功", allUser);
    }

    /**
     * 删除指定 id 用户
     *
     * @param id
     * @return
     */
    @Override
    public BaseResponse<Integer> deleteUserById(int id) {
        int flag = userMapper.deleteById(id);
        if (flag < 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除数据失败");
        }
        return new BaseResponse<>(CommonConstant.SUCCESS, "删除数据成功", flag);
    }

    /**
     * 分页查询
     *
     * @param currentPage 当前页面是第几页
     * @param pageSize    一页显示几条数据
     * @return
     */
    @Override
    public BaseResponse<List<User>> getUsersByPage(int currentPage, int pageSize) {
        int pageNo = (currentPage - 1) * pageSize;
        List<User> usersByPage = userMapper.getUsersByPage(pageNo, pageSize);
        return new BaseResponse<>(CommonConstant.SUCCESS, "查询成功", usersByPage);
    }

    /**
     * 获取用户总数
     *
     * @return
     */
    @Override
    public BaseResponse<Integer> getAllUsersCount() {
        int allUsersCount = userMapper.getAllUsersCount();
        return new BaseResponse<>(CommonConstant.SUCCESS, allUsersCount);
    }

    /**
     * 条件查询
     *
     * @param userQueryDto
     * @param pageNo
     * @param pageSize
     * @return
     */
    @Override
    public BaseResponse<List<User>> getUsersByCondition(UserQueryDto userQueryDto) {
        int currentPage = userQueryDto.getCurrentPage();
        int pageSize = userQueryDto.getPageSize();
        userQueryDto.setCurrentPage((currentPage - 1) * pageSize);
        List<User> users = userMapper.getUserByCondition(userQueryDto);
        return new BaseResponse<>(CommonConstant.SUCCESS, users);
    }
}




